package com.dai.nettyserve.netty.manager;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.buf.HexUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: 代
 * @Description: netty客户端操作类  封装给硬件发送消息的工具
 * @Date: Created in 18:17 2017/3/25
 */

@Slf4j
public class NettyClientStore {
    //存放设备ID和该设备ID对应的消息通道，以后往该设备ID发送消息即是往该设备对应的设备通道发送消息
    public static Map<String, ChannelHandlerContext> clientMap = new HashMap<String, ChannelHandlerContext>();
    //存放接收的最新的消息，只保存最新的接收的消息
    public static Map<String, StringBuilder> receiveMap = new HashMap<String, StringBuilder>();

    /**
     * 发送消息
     *
     * @param Msg    要发送的数据
     * @param gprsId 设备ID   字符串   非16进制
     */
    public static void sendMsg(String Msg, String gprsId) {
        //得到gprsId对应的channel通道，往通道里发送消息即向该通道对应的设备发送消息
//        NettyClientStore.clientMap.get(gprsId).writeAndFlush(StringToByteBuf(Msg));

        //
        if (null != NettyClientStore.clientMap.get(gprsId)) {
            log.info("主动推送的消息 ：{}", Msg);
            byte[] byteMsg = HexUtils.fromHexString(Msg);
            ByteBuf buf = Unpooled.wrappedBuffer(byteMsg);
            NettyClientStore.clientMap.get(gprsId).writeAndFlush(buf);
        } else {
            log.info("该sn没有上线");
        }


    }

    /**
     * 接收消息
     *
     * @return 要接收的消息
     */
    public static StringBuilder readMsg(String gprsId) {
        if (receiveMap.size() != 0) {
            return receiveMap.get(gprsId);
        } else {
            return new StringBuilder(new String("设备连接异常，请检查！"));
        }
    }

    /**
     * 字符串转ByteBuf
     *
     * @param Msg 要转换的字符串
     * @return ByteBuf类型数据
     */
    public static ByteBuf StringToByteBuf(String Msg) {
        // 把要发送的String数据转换成byte数组，对于仪表等二进制的数据接发送用下面的这个转换
        //byte[] bytes = NettyClientStore.hexStringToBytes(Msg);
        // 把要发送的String数据转换成byte数组，对于直接发送字符串的用下面的这个转换
        byte[] bytes = Msg.getBytes();
        // 创建ByteBuf类型
        ByteBuf b = Unpooled.buffer(Msg.length());
        // 将发送的命令数据读进ByteBuf中
        b.writeBytes(bytes);
        return b;
    }

    /**
     * 二进制字符串转字节数组
     *
     * @param hexString 二进制字符串
     * @return 字节数组
     */
    public static byte[] hexStringToBytes(String hexString) {
        hexString = hexString.replaceAll(" ", ""); // 去空格
        if ((hexString == null) || (hexString.equals(""))) {
            return null;
        }
        hexString = hexString.toUpperCase(); // 字符串中的所有字母都被转化为大写字母
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; ++i) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[(pos + 1)]));
        }
        return d;
    }

    /**
     * char转字节数
     *
     * @param c char
     * @return 字节数
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /**
     * 通用的得到数据校验位的方法
     *
     * @param Message 要发送的数据
     * @return 校验位
     * @throws NumberFormatException
     */
    public static String getCheckBit(String Message) throws NumberFormatException {
        byte[] bys = Message.getBytes();
        int checkBit = 0;
        for (int i = 0; i < bys.length; i++) {
            int c = (int) bys[i];
            if (c >= 48) {
                checkBit += c - 48;

            } else if (c < 48) {
                checkBit += (256 - (48 - c));
            }
            if (checkBit > 255) {
                checkBit -= 256;
            }
        }
        checkBit = checkBit % 10;
        return String.valueOf(checkBit);
    }


    public static void main(String[] args) {
        System.out.println("A5002F50f6303039304332434132304542313131313131313131313131DCCD01AAAAA10011E1015500000000CDDCa1".length() / 2);
    }
}
